const fs = require("fs");
const path = require("path");

function getEncodingData(fileName) {
  try {
    const encodingsDir = path.join(__dirname, "..", "encodings");
    return require(path.join(encodingsDir, fileName));
  } catch (e) {
    console.error(`Error reading ${fileName}:`, e);
    return {};
  }
}

function collectAllEncodings() {
  const allNames = new Set();
  const canonicalize = (name) => ("" + name).toLowerCase().replace(/:\d{4}$|[^0-9a-z]/g, "");

  const processEncodingObject = (obj) => {
    for (const key in obj) {
      // Skip codecs
      if (key.startsWith("_")) continue;

      const value = obj[key];
      allNames.add(key); // Add the alias itself

      if (typeof value === "string") {
        allNames.add(value); // Add the canonical name it points to
      } else if (typeof value === "object" && value.name) {
        allNames.add(value.name); // Add the name from the object
      }
    }
  };

  // Process all relevant files
  processEncodingObject(getEncodingData("internal.js"));
  processEncodingObject(getEncodingData("utf32.js"));
  processEncodingObject(getEncodingData("utf16.js"));
  processEncodingObject(getEncodingData("utf7.js"));
  processEncodingObject(getEncodingData("sbcs-codec.js"));
  processEncodingObject(getEncodingData("sbcs-data.js"));
  processEncodingObject(getEncodingData("sbcs-data-generated.js"));
  processEncodingObject(getEncodingData("dbcs-codec.js"));
  processEncodingObject(getEncodingData("dbcs-data.js"));

  // Add the canonicalized (lowercase, alphanumeric, no appended year) versions
  const finalNames = new Set();
  allNames.forEach((name) => {
    finalNames.add(name);
    const canon = canonicalize(name);
    if (canon) {
      finalNames.add(canon);
    }
  });

  return Array.from(finalNames).sort();
}

function generateTypingsFile() {
  const allEncodings = collectAllEncodings();
  const supportedEncodingType = allEncodings.map((name) => `  | "${name}"`).join("\n");

  const generatedHeader = `/*
 * ---------------------------------------------------------------------------------------------
 * DO NOT EDIT THIS FILE MANUALLY.
 * THIS FILE IS AUTOMATICALLY GENERATED.
 * TO UPDATE, RUN \`npm run typegen\` AND COMMIT THE CHANGES.
 * ---------------------------------------------------------------------------------------------
 */`;

  const fileContent = `${generatedHeader}\n
/** A union of all supported encoding strings in \`iconv-lite\`. */
export type Encoding =\n${supportedEncodingType}\n  | (string & {})
`;

  const outputPath = path.join(__dirname, "..", "types", "encodings.d.ts");
  fs.writeFileSync(outputPath, fileContent, "utf8");
}

// Run the script
generateTypingsFile();
